from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from applications.configs.database import USERNAME, PASSWORD, HOST, PORT, DATABASE

"""
1. 连接引擎
    参数：
        echo=False -- 如果为真，引擎将记录所有语句以及 repr() 其参数列表的默认日志处理程序。
        enable_from_linting -- 默认为True。如果发现给定的SELECT语句与将导致笛卡尔积的元素取消链接，则将发出警告。
        encoding -- 默认为 utf-8
        max_overflow=10 -- 允许在连接池中“溢出”的连接数，即可以在池大小设置（默认为5）之上或之外打开的连接数。
        pool_size=5 -- 在连接池中保持打开的连接数
        pool_recycle=200 多少秒后自动回收连接。这对MySQL是必要的,它默认移除闲置多于 8 小时的连接。注意如果 使用了 MySQL ， Flask-SQLALchemy 自动设定 这个值为 2 小时
    
    数据库连接字符串：  
        mysql: 'mysql+pymysql://{username}:{password}@{host}:{port}/{db}?charset=utf8',
        mssql: 'mssql+pymssql://{username}:{password}@{host}:{port}/{db}'
    
    多种连接方式：
        直接使用Engine.execute( ) 或 Connection.execute( )，更加灵活，可以使用原生SQL语句， Connection 可处理事务
        
        使用Session处理交易类型的数据，因为方便使用session.add(),session.rollback(),session.commit(),session.close()等，它是使用ORM时推荐的一种和数据库交互的方式；
        
2. ORM 基类
    from sqlalchemy.orm import declarative_base
    
3. ORM 数据库迁移
    1. pip install alembic
    2. alembic init alembic
        alembic.ini 配置数据库地址：
            sqlalchemy.url = mysql+pymysql://root:root@127.0.0.1:3306/reader?charset=utf8
        env.py
            1. 设置根目录  import sys   from os.path import abspath, dirname    sys.path.append(dirname(dirname(abspath(__file__))))
            2. 设置model位置  from applications.models import baseModel    target_metadata = baseModel.metadata
            
    3. 修改数据结构
        alembic revision --autogenerate -m "change pwd"     --autogenerate参数可以对字段做增删改       -m 添加注释
    4. 迁移数据库
        alembic upgrade head
"""

# 连接引擎
bing_str = f'mysql+pymysql://{USERNAME}:{PASSWORD}@{HOST}:{PORT}/{DATABASE}?charset=utf8'
engine = create_engine(bing_str, echo=False, pool_size=5, max_overflow=10, pool_recycle=60 * 60)

# 连接基类
baseModel = declarative_base()


# 获取会话
# 创建一个配置过的Session类
Session = sessionmaker(bind=engine, expire_on_commit=False)


# 获取一个会话
def get_session():
    session = Session()
    try:
        yield session
    finally:
        session.close()